package com.pi.base.service.impl;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.pi.base.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.pi.base.common.BasePage;
import com.pi.base.common.BaseResult;
import com.pi.base.constant.SysStatics;
import com.pi.base.encrypt.MD5Encrypt;
import com.pi.base.entity.SysGroup;
import com.pi.base.entity.SysMenu;
import com.pi.base.entity.SysRole;
import com.pi.base.entity.SysUser;
import com.pi.base.entity.SysUserExample;
import com.pi.base.mapper.BaseSysRoleMapper;
import com.pi.base.mapper.BaseSysUserMapper;
import com.pi.base.mapper.SysGroupMapper;
import com.pi.base.mapper.SysRoleMapper;
import com.pi.base.mapper.SysUserMapper;
import com.pi.base.service.ISysUserService;
import com.pi.base.util.CookieUtils;
import com.pi.base.util.MapBuilder;
import com.pi.base.util.PropKit;
import com.pi.base.util.SessionUtil;
import com.pi.base.util.ValidUtil;
import com.pi.base.vo.SysGroupVO;
import com.pi.base.util.bean.ObjectTool;

@Service("sysUserService")
public class SysUserService implements ISysUserService {

	private final Logger logger = LoggerFactory.getLogger(SysUserService.class);
			
	@Autowired
	private SysUserMapper sysUserMapper;
	@Autowired
	private SysRoleMapper sysRoleMapper;
	@Autowired
	private BaseSysRoleMapper baseSysRoleMapper;
	@Autowired
	private BaseSysUserMapper baseSysUserMapper;
	@Autowired
	private SysGroupMapper sysGroupMapper;

	@Override
	public BaseResult checkLogin(String userName, String password,HttpServletRequest request,HttpServletResponse response)
			throws Exception {
		//1.查询用户信息
		/*SysUserExample example = new SysUserExample();
		example.createCriteria().andUsernameEqualTo(userName).andPasswordEqualTo(MD5Encrypt.md5(password));*/
		SysUser loginUserQuery = new SysUser();
		loginUserQuery.setUsername(userName);
		loginUserQuery.setPassword(MD5Encrypt.md5(password));
		SysUser loginUser = sysUserMapper.selectOne(loginUserQuery);
		if(loginUser == null){
			return BaseResult.newErrorResult("用户名或者密码错误");
		}
		if(SysStatics.SysUserState_Del == loginUser.getUserstate()){ //删除状态
			return BaseResult.newErrorResult("用户名或者密码错误");
		}
		if(SysStatics.SysUserState_fbd == loginUser.getUserstate()){ //禁用状态
			return BaseResult.newErrorResult("您已经被管理员禁用，请联系管理员!");
		}
		
		//非超级管理员,查询管理员被分配的权限
		Integer roleId = loginUser.getRoleid();
		SysRole loginRole = sysRoleMapper.selectByPrimaryKey(roleId);
		//2.查询用户权限
		if (loginUser.getSuperadmin() == SysStatics.SysUser_NotSuperAdmin) { 
			if (roleId == null) {
				return BaseResult.newErrorResult("未给该用户分配角色，请联系管理员!");
			}
			if (loginRole == null) {  //角色不存在
				return BaseResult.newErrorResult("该用户的角色已被删除，请联系管理员分配新角色!");
			}
			List<SysMenu> sysMenuList = getAllMenuByRoleIdAndLevel(roleId,SysStatics.SysMenu_Level_Two);
			if(ValidUtil.isEmptyList(sysMenuList)){
				return BaseResult.newErrorResult("该用户的角色下面没有权限。请联系管理员给该角色分配权限!");
			}
			
			//2.1保存角色到session
			PropKit.use("tableMap.properties");
			Map<String, Object> map = new MapBuilder.Builder<Object>().
					map("groupId",loginUser.getGroupid()).
					map("tableName",PropKit.get("sys_group","sys_group")).
					build().map();
			List<Integer> subIdList = baseSysUserMapper.queryGroupWithSubIdsStrByID(map);
			String subIds = subIdList.toString().substring(1, subIdList.toString().length() - 1);
			
			SessionUtil.setSessionAttribute(request, SysStatics.WEB_GROUP_SESSION, subIds);
		}
    SessionUtil.setSessionAttribute(request, SysStatics.WEB_ROLE_SESSION, loginRole);
		//2.2 保存用户名到cookie
		CookieUtils.setCookie(response,SysStatics.WEB_USERNAME_COOKIE,userName);	
		//3.保存用户信息到session
		SessionUtil.setSessionAttribute(request, SysStatics.WEB_USER_SESSION, loginUser);
		return BaseResult.newSuccessResult("登录成功");
	}
	
	@Override
	public List<SysMenu> getAllMenuByRoleIdAndLevel(Integer roleId, Integer... level) throws Exception{
		PropKit.use("tableMap.properties");
		Map<String, Object> map = new MapBuilder.Builder<Object>().
				map("roleId",roleId).
				map("function1",PropKit.get("queryMenuWithParentByRoleId","queryMenuWithParentByRoleId")).
				build().map();
		
		String s = baseSysRoleMapper.queryMenuWithParentByRoleIdFunc(map);
		logger.debug("s:::"+s);
		Map<String, String> params = new HashMap<String, String>();
		params.put("roleId", roleId + "");
		if (level.length > 0) {
			String levelStr = "";
			for (int i = 0; i < level.length; i++) {
				if (i == 0) {
					levelStr += level[i];
				}
				levelStr += "," + level[i];
			}
			params.put("levelIn", levelStr);
		}
		if (s.startsWith("$")) {
			s = s.substring(2);
		}
		params.put("menuWithParentByRoleIdResultStr", s);
		PropKit.use("tableMap.properties");
		String table_sys_menu = PropKit.get("sys_menu","sys_menu");
		params.put("tableName", table_sys_menu);
		return baseSysRoleMapper.queryAllMenuByRoleIdAndLevel(params);
		
	}

	@Override
	public boolean updateUserPwd(SysUser loginUser) throws Exception {
		SysUser sysUser = new SysUser();
		sysUser.setId(loginUser.getId());
		sysUser.setPassword(loginUser.getPassword());
		return sysUserMapper.updateByPrimaryKeySelective(sysUser) > 0;
	}

	@Override
	public List<SysGroup> getGroupWithSubListByGroupId(String groupId)
			throws Exception {
		PropKit.use("tableMap.properties");
		Map<String, String> params = new MapBuilder.Builder<String>().
				map("tableSysUser",PropKit.get("sys_user","sys_user")).
				map("tableSyGroup",PropKit.get("sys_group","sys_group")).
				map("function1",PropKit.get("queryGroupWithSubByID","queryGroupWithSubByID")).
				map("groupId",groupId).build().map();
		return baseSysUserMapper.queryGroupWithSubByID(params);
	}

	
	@Override
	public List<SysGroupVO> getGroupWithSubListByGroupId2(String groupId)
			throws Exception {
		PropKit.use("tableMap.properties");
		Map<String, String> params = new MapBuilder.Builder<String>().
				map("tableSyGroup",PropKit.get("sys_group","sys_group")).
				map("function1",PropKit.get("queryGroupWithSubByID","queryGroupWithSubByID")).
				map("groupId",groupId).build().map();
		/*Map<String, String> params = new MapBuilder.Builder<String>().
				map("groupId",groupId).build().map();*/
		return baseSysUserMapper.queryGroupWithSubByID2(params);
	}

	
	@Override
	public BasePage<SysUser> listSysUserByGroupID(Map<String, Object> params,
			int groupId,boolean superState) throws Exception {
		PropKit.use("tableMap.properties");
		Map<String, Object> map = new MapBuilder.Builder<Object>().
				map("groupId",groupId).
				map("tableName",PropKit.get("sys_group","sys_group")).
				build().map();
	    
		List<Integer> subIds = baseSysUserMapper.queryGroupWithSubIdsStrByID(map);
	    if(superState){ //是超级管理员
	    	subIds.add(0);
	    }
	    StringBuilder groupStr = new StringBuilder("");
	    for(int i = 0 ; i < subIds.size(); i++){
	    	if(i == 0){
	    		groupStr.append(subIds.get(i));
	    	}else{
	    		groupStr.append(",").append(subIds.get(i));
	    	}
	    }
	  
	    PropKit.use("tableMap.properties");
	    Map<String, Object> newParams = new HashMap<String,Object>();
	    newParams.putAll(params);
	    newParams.put("tableSysUser", PropKit.get("sys_user","sys_user"));
	    newParams.put("tableSysRole", PropKit.get("sys_role","sys_role"));
	    newParams.put("groupIds", groupStr);
	    List<SysUser> userList = baseSysUserMapper.listSysUserByGroupID(newParams);
	    long countUserList = baseSysUserMapper.countListSysUserByGroupID(newParams);
	    return  new BasePage<SysUser>(countUserList,userList);
		
		
	}

	@Override
	public SysUser sysUserInfoById(int userId) throws Exception {
		SysUser sysUser = sysUserMapper.selectByPrimaryKey(userId);
		if(sysUser != null && sysUser.getRoleid() != null && sysUser.getSuperadmin() == 0){
			SysRole sysRole = sysRoleMapper.selectByPrimaryKey(sysUser.getRoleid());
			if(sysRole != null){
				sysUser.setRolename(sysRole.getName());
			}
		}
		return sysUser;
	}

	@Override
	public boolean existSysUserName(SysUser searchUser) throws Exception {
		if(searchUser.getId() == null){
			return sysUserMapper.selectCount(searchUser) > 0;
		}else{
			SysUserExample example = new SysUserExample();
			SysUserExample.Criteria criteria = example.createCriteria();
			criteria.andIdNotEqualTo(searchUser.getId());
			if(!ValidUtil.isBlank(searchUser.getUsername())){
				criteria.andUsernameEqualTo(searchUser.getUsername());
			}/*else if(!ValidUtil.isBlank(searchUser.getCode())){
				criteria.andCodeEqualTo(searchUser.getCode());
			}*/
			return sysUserMapper.selectCountByExample(example) > 0;
		}
		
	}

	@Override
	public BaseResult insertSysUser(SysUser insertUser) throws Exception {

		//1.查询group的根节点
		if(insertUser.getAreaid() == null){
			SysGroup group = sysGroupMapper.selectByPrimaryKey(insertUser.getGroupid());
			if (group == null) {
				return BaseResult.newErrorResult("分组不存在");
			}
			if (group.getType() < 2) {
				// 如果是总公司或分公司
				insertUser.setAreaid(group.getId());
				insertUser.setAreaname(group.getName());
				insertUser.setAreaeasyname(group.getCode());			
			}else{
				PropKit.use("tableMap.properties");
				Map<String,Object> params = new MapBuilder.Builder<Object>().
						map("groupId",group.getId()).
						map("groupType","1").
						map("tableSyGroup",PropKit.get("sys_group","sys_group")).
						map("function1",PropKit.get("queryGroupWithParentByID","queryGroupWithParentByID")).build().map();
				List<SysGroup> groupList = baseSysUserMapper.queryGroupWithParentByID(params);
				if(ValidUtil.isEmptyList(groupList)){
					return BaseResult.newErrorResult("分组信息异常");
				}
				SysGroup subComp = groupList.get(0);
				insertUser.setAreaid(subComp.getId());
				insertUser.setAreaname(subComp.getName());
				insertUser.setAreaeasyname(subComp.getCode());
			}
	
			
		}
		sysUserMapper.insertSelective(insertUser);
		return BaseResult.newSuccessResult("新增用户成功");
	}

	@Override
	public void deleteSysUsers(List<Integer> userIdList) throws Exception {
		SysUserExample example = new SysUserExample();
		example.createCriteria().andIdIn(userIdList);
		sysUserMapper.deleteByExample(example);
	}

	@Override
	public void updateSysUser(SysUser updateUser) throws Exception {
		sysUserMapper.updateByPrimaryKeySelective(updateUser);
	}

	@Override
	public void userRoleSetByUserIdsAndRoleIdAndName(List<Integer> userIdList,
			Integer roleId, String roleName) throws Exception {
		SysUserExample example = new SysUserExample();
		example.createCriteria().andIdIn(userIdList);
		SysUser record = new SysUser();
		record.setRoleid(roleId);
		record.setRolename(roleName);
		sysUserMapper.updateByExampleSelective(record, example);
	}

	@Override
	public BaseResult userGroupSetByUserIdsAndGroupId(List<Integer> userIdList, Integer groupId)
			throws Exception {
		SysUserExample example = new SysUserExample();
		example.createCriteria().andIdIn(userIdList);
		SysUser record = new SysUser();
		record.setGroupid(groupId);
		
		SysGroup group = sysGroupMapper.selectByPrimaryKey(groupId);
		
		if (group == null) {
			return BaseResult.newErrorResult("分组不存在");
		}
		record.setGroupname(group.getName());
		if (group.getType() < 2) {
			// 如果是总公司或分公司
			record.setAreaid(group.getId());
			record.setAreaname(group.getName());
			record.setAreaeasyname(group.getCode());			
		}else{
			PropKit.use("tableMap.properties");
			Map<String,Object> params = new MapBuilder.Builder<Object>().
					map("groupId",groupId).
					map("groupType","1").map("tableSyGroup",PropKit.get("sys_group","sys_group")).
					map("function1",PropKit.get("queryGroupWithParentByID","queryGroupWithParentByID")).
					build().map();
			List<SysGroup> groupList = baseSysUserMapper.queryGroupWithParentByID(params);
			if(ValidUtil.isEmptyList(groupList)){
				return BaseResult.newErrorResult("分组信息异常");
			}
			SysGroup subComp = groupList.get(0);
			record.setAreaid(subComp.getId());
			record.setAreaname(subComp.getName());
			record.setAreaeasyname(subComp.getCode());
		}
	
		sysUserMapper.updateByExampleSelective(record, example);
		return BaseResult.newSuccessResult("更新成功");
	}

	@Override
	public void userPasswordResetByUserIds(List<Integer> userIdList,
			String newPassword) throws Exception {
		SysUserExample example = new SysUserExample();
		example.createCriteria().andIdIn(userIdList);
		SysUser record = new SysUser();
		record.setPassword(MD5Encrypt.md5(newPassword));
		sysUserMapper.updateByExampleSelective(record, example);
	}

	@Override
	public void userStateSetByUserIds(List<Integer> userIdList, int userState)
			throws Exception {
		SysUserExample example = new SysUserExample();
		example.createCriteria().andIdIn(userIdList);
		SysUser record = new SysUser();
		record.setUserstate(userState);
		sysUserMapper.updateByExampleSelective(record, example);
		
	}

	@Override
	public List<SysUser> listSysUserByIds(List<Integer> userIdList)
			throws Exception {
		SysUserExample example = new  SysUserExample();
		example.createCriteria().andIdIn(userIdList);
		return sysUserMapper.selectByExample(example);
	}

  
  /**
   * @description 根据账号修改用户信息
   * @param user 用户信息包装类
   * @return
   * @throws SQLException
   */
  public boolean updateUserInfo(SysUser appUser) throws SQLException{
  //查询系统用户的属性(管理员，经销商级别还是工作人员)
    SysUser user = querySysUserInfo(appUser.getUsername());
    //超级管理员只在后台注册(修改SysUser信息)
    //系统用户包装类
    SysUser sysUser = new SysUser();
    if(null != appUser.getPassword()){
      sysUser.setPassword(MD5Encrypt.md5(appUser.getPassword()));
    }
    sysUser.setUsername(appUser.getUsername());
    sysUser.setNickname(appUser.getNickname());
    sysUser.setAddress(appUser.getAddress());
    sysUser.setPhoneimg(appUser.getPhoneimg());
    sysUser.setId(user.getId());
    sysUserMapper.updateByPrimaryKeySelective(sysUser);
    if(user.getSuperadmin() == SysStatics.SysUser_IsSuperAdmin){
      //系统用户数据已更新
    }else{
      throw new ServiceException("该账号的人员类型不明确");
    }
    return true;
  }
  
  /**
   * @description 根据账号查询系统用户
   * @param account
   * @return
   * @throws SQLException
   */
  public SysUser querySysUserInfo(String account,boolean... throwable) throws SQLException{
    SysUserExample userExample = new SysUserExample();
    userExample.createCriteria().andUsernameEqualTo(account);
    SysUser sysUser = ObjectTool.getOne(sysUserMapper.selectByExample(userExample));
    if(null == sysUser){
      if(null == throwable || throwable.length == 0 || (throwable.length>0 && throwable[0])){        
        throw new ServiceException("系统用户不存在");
      }else{
        return null;
      }
    }else{
      return sysUser;
    }
  }  
  
}
